"""
1、下面程序的功能是：验证四方定理，即所有自然数至多只需四个数的平方和就可以表示，请找出错误并修改验证。
四方定理指出：任何自然数都可以表示为最多4个整数的平方和
比如：
5 = 1² + 2²
7 = 1² + 1² + 1² + 2²
20 = 2² + 4² 或 1² + 1² + 3² + 3²
"""


# 错误代码
# def sum_square(n):
#     for i in range(1, n / 2 + 1):
#         for j in range(1, i + 1):
#             for k in range(1, i + 1):
#                 for l in range(1, i + 1):
#                     if n == i * i + j * j + k * k + 1 * 1:
#                         print(n, '=', i, '*', i, '+', j, '*', j, '+', k, '*', k, '+', 1, '*', 1)
#
#
# sum_square(20)

# 正确代码
def sum_squre(n):
    for i in range(1, n // 2 + 1):
        for j in range(1, i + 1): #
            for k in range(1, i + 1):
                for l in range(1, i + 1):
                    if n == i * i + j * j + k * k + l * l:
                        print(n, '=', i, '*', i, '+', j, '*', j, '+',
                              k, '*', k, '+', l, '*', l)


sum_squre(20)

"""
2、下面程序的功能是：解决买水问题，输入钱数，输出可买水的瓶数。规则如下：1元钱可以买1瓶水，2个空瓶可以换1瓶水，3个瓶盖也可以换1瓶水。请找出错误并修改验证。
"""
# 错误代码
# Water = int(input('请输入钱数：'))
# # 定义买水的函数，nW 表示新水的数量，nB 表示新瓶的数量，nL 表示新盖的数量
# def f(nW, nB, nL):
#     global Water, bottle, lid
#     bottle = nB + nW
#     lid = nL + nW
#     nW = bottle // 2 + lid
#     Water += nW
#     bottle = bottle %
#     lid = lid % 3
#     if (nB < 2 or nL < 3 or nW < 1):
#         return
#     else:
#         f(nW, nB, nL)
# f(Water, 0, 0)
# print(Water)
# 正确代码
Water = int(input('请输入钱数：'))
# 定义买水的函数，nW 表示新水的数量，nB 表示新瓶的数量，nL 表示新盖的数量
def f(nW, nB, nL):
    global Water, bottle, lid
    bottle = nB + nW
    lid = nL + nW
    nW = bottle // 2 + lid // 3
    Water += nW
    nB = bottle % 2
    nL = lid % 3
    if (nB < 2 and nL < 3 and nW < 1):
        return
    else:
        f(nW, nB, nL)
f(Water, 0, 0)
print(Water)
"""
以3瓶为例：
第一轮兑换：
空瓶：3÷2=1瓶水（余1空瓶）
瓶盖：3÷3=1瓶水（余0瓶盖）
共换得2瓶水
喝完后：1+2=3个空瓶 + 0+2=2个瓶盖
累计：3+2=5瓶

第二轮兑换：
空瓶：3÷2=1瓶水（余1空瓶）
瓶盖：2÷3=0瓶水（余2瓶盖）
共换得1瓶水
喝完后：1+1=2个空瓶 + 2+1=3个瓶盖
累计：5+1=6瓶

第三轮兑换：
空瓶：2÷2=1瓶水（余0空瓶）
瓶盖：3÷3=1瓶水（余0瓶盖）
共换得2瓶水
喝完后：0+2=2个空瓶 + 0+2=2个瓶盖
累计：6+2=8瓶

第四轮兑换：
空瓶：2÷2=1瓶水（余0空瓶）
瓶盖：2÷3=0瓶水（余2瓶盖）
共换得1瓶水
喝完后：0+1=1个空瓶 + 2+1=3个瓶盖
累计：8+1=9瓶

第五轮兑换：
空瓶：1÷2=0瓶水（余1空瓶）
瓶盖：3÷3=1瓶水（余0瓶盖）
共换得1瓶水
喝完后：1+1=2个空瓶 + 0+1=1个瓶盖
累计：9+1=10瓶

第六轮兑换：
空瓶：2÷2=1瓶水（余0空瓶）
瓶盖：1÷3=0瓶水（余1瓶盖）
共换得1瓶水
喝完后：0+1=1个空瓶 + 1+1=2个瓶盖
累计：10+1=11瓶
"""


"""
下面程序的功能是：设计一个函数，判断传入的整数列表（要求元素个数大于2）中的元素能否构成等差数列（从第二项起，每一项与它的前一项的差等于同一个常数），如果能，返回“构成等差数列”，否则返回“不能构成等差数列”。请将正确答案写在横线处。

小提示：eval（）函数用于执行一个字符串表达式，并返回表达式的值。例如, eval（'[1,2,3,4]'）的结果为列表[1,2,3,4].

def Isf(list_number):
    d = _______              							#求公差d
    for i in range(1, len(list_number) - 1):
        if _______:
            return '构成等差数列'
        else:
            return '不能构成等差数列'
list = eval(input('请输入一个整数数列（元素个数大于2）：'))
print('此数列', _______)

"""


def Isf(list_number):
    d = list_number[1] - list_number[0]  # 求公差d
    for i in range(1, len(list_number) - 1):
        if d == list_number[i + 1] - list_number[i]:
            return '构成等差数列'
        else:
            return '不能构成等差数列'


list = eval(input('请输入一个整数数列（元素个数大于2）：'))
print('此数列', Isf(list))


"""
一般来说，正常的邮件中不会出现太多类似于【、】、*、\、/、+、-这样的符号，如果一封邮件中包含的类似字符数量超过一定的比例，可以直接认为它是垃圾邮件。下面程序的功能是：根据给定的邮件内容进行分类，提示“垃圾邮件”或“正常邮件”。请将正确答案写在横线处

def check(text, rate=0.2):
    characters = '【】*-/\\'
    num = 0
    for ch in characters:
        if ch in text:
            _______
    if _______:
        return '垃圾邮件'
    return '正常邮件'
text = '我公【司免【开发】票微-信同*号'
print(_______)
"""
def check(text, rate=0.2):
    characters = '【】*-/\\'
    num = 0
    for ch in characters:
        if ch in text:
            num += num + text.count(ch)
    if num / len(text) > rate:
        return '垃圾邮件'
    return '正常邮件'
text = '我公【司免【开发】票微-信同*号'
print(check(text))

"""
编写函数，接收两个正整数作为参数，返回一个元组，其中第一个元素为两个正整数的最大公约数，第二个元素为其最小公倍数，输出最大公约数和最小公倍数。
"""
def demo(m, n):
    p = m * n
    while m % n != 0:
        m, n = n, m % n
    return n, p // n
a = int(input('请输入其中一个整数：'))
b = int(input('请输入另一个整数：'))
c = demo(a, b)
print('{}和{}的最大公约数为{}'.format(a, b, c[0]))
print('{}和{}的最小公倍数为{}'.format(a, b, c[1]))
"""
核心算法：辗转相除法
辗转相除法的原理：两个数的最大公约数等于其中较小的数和两数相除余数的最大公约数。

以12 和 18 为例
初始状态：
m = 12, n = 18
p = m × n = 12 × 18 = 216（保存乘积用于计算最小公倍数）

第一次循环：
条件：m % n = 12 % 18 = 12 ≠ 0（进入循环）
执行：m, n = n, m % n → m=18, n=12

第二次循环：
条件：m % n = 18 % 12 = 6 ≠ 0（进入循环）
执行：m, n = n, m % n → m=12, n=6

第三次循环：
条件：m % n = 12 % 6 = 0（退出循环）

返回结果：
最大公约数 = n = 6
最小公倍数 = p ÷ n = 216 ÷ 6 = 36
"""

"""
编写函数，求三个数中最大值。
"""
def getMax(num1,num2,num3):
    if num1 > num2:
        temp = num1
    else:
        temp = num2
    if temp > num3:
        return "其中最大值为：" + str(temp)
    else:
        return "其中最大值为：" + str(num3)

a = int(input('请输入第1个整数：'))
b = int(input('请输入第2个整数：'))
c = int(input('请输入第3个整数：'))
maxValue = getMax(a, b, c)
print(maxValue)


"""
用递归方法计算S=1+2+3+…+n.
"""
def f(n):
    if n == 1:
        return 1
    else:
        return f(n - 1) + n
n = int(input('请输入一个正整数：'))
print('S=1+2+3+…+n:',f(n))

"""
哥德巴赫猜想：每个不小于 6 的偶数都是两个奇素数之和。编写程序，验证哥德巴赫猜想对20以内的正偶数成立。
"""
def prime(i):							#定义函数，判断i是否为素数
    if i <= 1:						#如果小于等于1，返回0（i不是素数）
        return 0
    if i == 2:						#如果等于2，返回1（i是素数）
        return 1
    for j in range(2, i):			#判断i是否为素数
        if i % j == 0:				#i可以被j除尽，余数为0
            return 0					#返回0，i不是素数
        elif i != j + 1:				#如果i不等于j+1，继续
            continue
        else:
            return 1					#否则，i等于j+1，返回1（i是素数）
n = 0
for i in range(6, 21, 2):
    k = 2
    while k <= i/2:
        j = i - k
        flag1 = prime(k)				#调用prime函数
        if flag1:						#如果k为素数
            flag2 = prime(j)			#调用prime函数
            if flag2:					#如果k和j都是素数
                print(i, '=', k, '+', j)		#输出结果
                n += 1
        k = k + 1
"""
素数就是大于1的自然数，而且它只有1和它自己本身这两个因数
第一步：i = 8
k从2开始，检查到4（因为8/2=4）

第一次循环：k = 2
j = 8 - 2 = 6
prime(2) = 1（2是素数）
prime(6) = 0（6不是素数）
不满足条件，继续

第二次循环：k = 3
j = 8 - 3 = 5
prime(3) = 1（3是素数）
prime(5) = 1（5是素数）
满足条件，输出：8 = 3 + 5

第三次循环：k = 4
j = 8 - 4 = 4
prime(4) = 0（4不是素数）
不满足条件，结束
完整验证结果
程序会依次验证6到20的所有偶数：
6 = 3 + 3
8 = 3 + 5
10 = 3 + 7 或 5 + 5
12 = 5 + 7
14 = 3 + 11 或 7 + 7
16 = 3 + 13 或 5 + 11
18 = 5 + 13 或 7 + 11
20 = 3 + 17 或 7 + 13
"""